﻿using System.Collections.Generic;
using OpenTK;

namespace Chimp.Core
{
    public class ChimpMaterial
    {
        #region LightingType enum

        /// <summary>
        /// Engine internal.
        /// </summary>
        public enum LightingType
        {
            Directional = 0,
            Point = 1,
            Spot = 2
        }

        #endregion

        #region MaterialFlags enum

        public enum MaterialFlags
        {
            Lit,
            X2D,
            Generic
        }

        #endregion

        public static Dictionary<string, ChimpMaterial> MatMap = new Dictionary<string, ChimpMaterial>();

        public ChimpMaterial(string name)
        {
            Name = name;

            Flags = MaterialFlags.Lit;
            ResetMaterial();
        }

        public ChimpMaterial(string name, MaterialFlags flags)
        {
            Name = name;


            Flags = flags;
            ResetMaterial();
        }

        /// <summary>
        /// Set by the engine, do not concern yourself with it.
        /// </summary>
        public LightingType LightType { get; set; }


        public bool NoLit { get; set; }
        public string Name { get; set; }
        public ChimpTexture2D DiffuseMap { get; set; }
        public ChimpTexture2D NormalMap { get; set; }
        public ChimpTexture2D HeightMap { get; set; }
        public ChimpTexture2D GlowMap { get; set; }
        public ChimpTexture2D ModMap { get; set; }
        public Matrix4 WorldMatrix { get; set; }
        public Matrix4 WorldRotationMatrix { get; set; }
        public Vector4 DiffuseColor { get; set; }
        public Vector4 SpecularColor { get; set; }
        public float SpecularPower { get; set; }

        public MaterialFlags Flags { get; set; }
        public ChimpEffect Effect { get; set; }
        public bool AutoEffectParameters { get; set; }

        public void ResetMaterial()
        {
            DiffuseMap = NormalMap = HeightMap = GlowMap = null;
            Effect = null;
            if (Flags == MaterialFlags.Lit)
            {
            }
            AutoEffectParameters = true;

            DiffuseColor = new Vector4(1, 1, 1, 1);
            SpecularColor = new Vector4(1, 1, 1, 1);
            SpecularPower = 0.0f;
            LightType = LightingType.Point;
            NoLit = false;
        }

        /// <summary>
        /// The base XenoEffect class is set up automagically by the engine. Use it wisely, luke.
        /// </summary>
        public void Bind()
        {
            if (DiffuseMap != null) DiffuseMap.Bind(0);
            if (NormalMap != null) NormalMap.Bind(1);
            // GL.Viewport(new System.Drawing.Point(0, 0), new System.Drawing.Size((int)XenoCore.DisplayWidth,(int) XenoCore.DisplayHeight));


            if (Effect != null)
            {
                Effect.Use();
            }

            if (AutoEffectParameters && Effect != null)
            {
                int Flag;
                if (NoLit)
                {
                    Flag = 0;
                }
                else
                {
                    Flag = 1;
                }
                Effect.SetInt("MaterialLightingBit", Flag);

                Effect.SetMat4("NodeWorldMatrix", WorldMatrix, false);
                Effect.SetMat4("NodeRotationMatrix", WorldRotationMatrix, false);
                Effect.SetInt("MaterialLightType", (int) LightType);
                Effect.SetVec4("MaterialDiffuseColor", DiffuseColor);
                Effect.SetVec4("MaterialSpecularColor", SpecularColor);
                Effect.SetFloat("MaterialSpecularPower", SpecularPower);

                Effect.SetInt("MaterialDiffuseMap", 0);
                Effect.SetInt("MaterialNormalMap", 1);
                bool dm = false;
                bool nm = false;

                if (DiffuseMap != null)
                {
                    Effect.SetInt("DiffuseMapping", 1);
                }
                else
                {
                    Effect.SetInt("DiffuseMapping", 0);
                }

                if (NormalMap != null)
                {
                    Effect.SetInt("NormalMapping", 1);
                }
                else
                {
                    Effect.SetInt("NormalMapping", 0);
                }
            }
        }

        public void Unbind()
        {
            if (Effect != null)
            {
                Effect.Fin();
            }
            if (NormalMap != null) NormalMap.Unbind(1);
            if (DiffuseMap != null) DiffuseMap.Unbind(0);


            if (DiffuseMap != null) DiffuseMap.Unbind(0);
        }
    }
}